#pragma once

#include "Props.h"
#include "SpringScrollViewConfigurator.h"
#include "RNOH/arkui/ArkUINode.h"
#include "RNOH/arkui/StackNode.h"
#include "EventEmitters.h"
#include "Types.h"
#include "RNOH/EventDispatcher.h"
#include "RNOH/arkui/ScrollNode.h"


namespace rnoh {

    class SpringScrollViewNodeDelegate {
    public:
        virtual ~SpringScrollViewNodeDelegate() = default;
        virtual void onRefresh(){};
        virtual void onLoading(){};
        virtual void onTouchBegin(){};
        virtual void onTouchEnd(){};
        virtual void onMomentumScrollBegin(){};
        virtual void onMomentumScrollEnd(){};
        virtual void onScroll(){};
        virtual void onSizeChange(){};
        virtual void onContentSizeChange(){};
    };

    class SpringScrollViewNode : public ArkUINode {
    protected:
        ArkUI_NodeHandle m_headerArkUINodeHandle;
        ArkUI_NodeHandle m_scrollArkUINodeHandle;
        ArkUI_NodeHandle m_footerArkUINodeHandle;
        SpringScrollViewNodeDelegate *m_scrollNodeDelegate;
        SpringScrollViewConfigurator springScrollViewConfigurator{SpringScrollViewConfigurator()};

    public:
        SpringScrollViewNode();
        ~SpringScrollViewNode() override;
        void insertChild(ArkUINode &child, std::size_t index);
        void removeChild(ArkUINode &child);
        void setSpringScrollViewNodeDelegate(SpringScrollViewNodeDelegate *springScrollViewNodeDelegate);
        SpringScrollViewConfigurator getSpringScrollViewConfigurator() { return springScrollViewConfigurator; }
       
        friend  class ScrollNode ;
        void onNodeEvent(ArkUI_NodeEventType eventType, EventArgs &eventArgs) override;
        void setInitialContentOffset(float x, float y);
        void setPageSize(float width, float height);
        void setRefreshHeaderHeight(float height);
        void setLoadingFooterHeight(float height);
        void setDecelerationRate(float rate);
        void setBounces(bool bounces);
        void setScrollEnabled(bool scrollEnabled);
        void setInverted(bool inverted);
        void setAllLoaded(bool allLoaded);
        void setDirectionalLockEnabled(bool directionalLockEnabled);
        void setContentOffset(float x, float y);
        void setPagingEnabled(bool pagingEnabled);

        void endLoading(bool rebound);
        void endRefresh();
        void scrollTo(float x, float y, bool animated);
//         void receiveCommand(SpringScrollViewNode &scrollView, const std::string &commandId,
//                             const std::vector<bool> &args);

    private:
        Types::Offset contentOffset{0.0f, 0.0f};
        Types::Offset initialContentOffset{0.0f, 0.0f};
        Types::Size size{0.0f, 0.0f};
        Types::Size contentSize{0.0f, 0.0f};
        Types::Size pageSize{0.0f, 0.0f};
        Types::Point lastPoint{0.0f, 0.0f};
        Types::Point beginPoint{0.0f, 0.0f};
        Types::EdgeInsets contentInsets{0.0f, 0.0f, 0.0f, 0.0f};

        
        EventDispatcher events;
        float refreshHeaderHeight;
        float loadingFooterHeight;
        float decelerationRate;
        bool bounces;
        bool scrollEnabled;
        bool inverted;
        bool allLoaded;
        bool directionalLockEnabled;
        bool pagingEnabled;
        bool momentumScrolling;
        bool dragging;
        std::string draggingDirection;
        std::string refreshStatus;
        std::string loadingStatus;
        ArkUI_IntOffset *arkUI_IntOffset = 0;

        void onMove(ArkUI_UIInputEvent *evt);
        void onDown(ArkUI_UIInputEvent *evt);
        void onUp(ArkUI_UIInputEvent *evt){};
        void drag(float x, float y);
        float getYDampingCoefficient();
        float getXDampingCoefficient();
        void moveToOffset(float x, float y);
        float getPageWidth();
        float getPageHeight();
        bool overshootVertical();
        bool overshootHead();
        bool overshootFooter();
        bool overshootLoading();
        bool overshootRefresh();
        bool overshootLeft();
        bool overshootRight();
        bool overshootHorizontal();
        bool shouldPulling();
        bool shouldPullingEnough();
        bool shouldRefresh();
        bool shouldPullingCancel();
        bool shouldWaiting();
        bool shouldDragging();
        bool shouldDraggingEnough();
        bool shouldLoad();
        bool shouldDraggingCancel();
        bool shouldFooterWaiting();
        bool canHorizontalScroll();
        void onHorizontalAnimationEnd(){};
        void onVerticalAnimationEnd(){};
    };
} // namespace rnoh